<!DOCTYPE html>
<html>
<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="utf-8">
  

  
  <title>Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta property="og:type" content="website">
<meta property="og:title" content="Hexo">
<meta property="og:url" content="http://yoursite.com/page/2/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:locale" content="default">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Hexo">
  
    <link rel="alternate" href="/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link rel="stylesheet" href="/css/style.css">
</head>
</html>
<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">Hexo</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://yoursite.com"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main">
  
    <article id="post-Dart语言简介" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/11/09/Dart语言简介/" class="article-date">
  <time datetime="2019-11-09T13:20:44.000Z" itemprop="datePublished">2019-11-09</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/Dart/">Dart</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/11/09/Dart语言简介/">Dart语言简介</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<h2 id="变量声明"><a href="#变量声明" class="headerlink" title="变量声明"></a>变量声明</h2><h3 id="var"><a href="#var" class="headerlink" title="var"></a><code>var</code></h3><p>类似于 JavaScript 中的 <code>var</code>，它可以定义变量</p>
<p>最大的不同是 Dart 中 <code>var</code> 变量一旦赋值，类型便会确定，不能改变其类型</p>
<h3 id="dynamic-和-Object"><a href="#dynamic-和-Object" class="headerlink" title="dynamic 和 Object"></a><code>dynamic</code> 和 <code>Object</code></h3><p><code>Object</code> 是 Dart 所有对象的根基类，也就是说所有类型都是 <code>Object</code> 的子类（包含 Function 和 NULL），所以任何类型的数据都可以赋值给 <code>Object</code> 声明的对象，<code>dynamic</code> 与 <code>var</code> 一样都是关键词，声明的变量可以赋值任意对象。</p>
<h4 id="相同之处"><a href="#相同之处" class="headerlink" title="相同之处"></a>相同之处</h4><p><code>dynamic</code> 与 <code>Object</code> 声明的变量可以在后期改变赋值类型</p>
<h4 id="不同之处"><a href="#不同之处" class="headerlink" title="不同之处"></a>不同之处</h4><p><code>dynamic</code> 声明的对象编译器会提供所有可能的组合，而 <code>Object</code> 声明的对象只能使用 <code>Object</code> 的属性和方法，否则编译器会报错</p>
<h3 id="final-和-const"><a href="#final-和-const" class="headerlink" title="final 和 const"></a><code>final</code> 和 <code>const</code></h3><p>如果你从未打算更改一个变量，那么使用 <code>final</code> 或 <code>const</code>，不是 <code>var</code>，也不是一个类型。一个 <code>final</code> 变量只能被设置一次。被 <code>final</code> 或者 <code>const</code> 修饰的变量，变量类型可以省略</p>
<h4 id="不同之处-1"><a href="#不同之处-1" class="headerlink" title="不同之处"></a>不同之处</h4><p><code>const</code> 变量是一个编译时常量，<code>final</code> 变量在第一次使用时被初始化</p>
<h2 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h2><p>Dart 是一种真正的面向对象的语言，所以即使是函数也是对象，并且有一个类型 Function。这意味着函数可以赋值给变量或作为参数传递给其他函数，这是函数式编程的典型特征</p>
<h3 id="函数声明"><a href="#函数声明" class="headerlink" title="函数声明"></a>函数声明</h3><p>Dart 函数声明如果没有显式声明返回值类型时会默认当做 <code>dynamic</code> 处理，注意，函数返回值没有类型推断</p>
<h3 id="可选的位置参数"><a href="#可选的位置参数" class="headerlink" title="可选的位置参数"></a>可选的位置参数</h3><p>包装一组函数参数，用<code>[]</code>标记为可选的位置参数</p>
<h3 id="可选的命名参数"><a href="#可选的命名参数" class="headerlink" title="可选的命名参数"></a>可选的命名参数</h3><p>定义函数时，使用<code>{param1, param2,...}</code>，用于指定命名参数</p>
<p>调用函数时，可以传参。如果传参，就必须使用指定形参的名称。例如：<code>paramName: value</code></p>
<h2 id="异步支持"><a href="#异步支持" class="headerlink" title="异步支持"></a>异步支持</h2><p>Dart 类库有非常多的返回 <code>Future</code> 或者 <code>Stream</code> 对象的函数。这些函数被称为 <strong>异步函数</strong> ：它们只会在设置好一些耗时操作之后返回，比如像IO操作。而不是等到这个操作完成</p>
<p><code>async</code> 和 <code>await</code> 关键词支持了异步编程，允许我们写出和同步代码很像的异步代码</p>
<h3 id="Future"><a href="#Future" class="headerlink" title="Future"></a><code>Future</code></h3><p><code>Future</code> 与 JavaScript 中的 <code>Promise</code> 非常相似，表示一个异步操作的最终完成（或失败）及其结果值的表示。简单来说，它就是用于处理异步操作的，异步处理成功了就执行成功的操作，异步操作失败了就捕获错误或者停止后续操作。一个 <code>Future</code> 只会对应一个结果，要么成功，要么失败</p>
<p><code>Future</code> 的所有 API 的返回值仍然是一个 <code>Future</code> 对象，所以可以很方便的进行链式调用</p>
<h4 id="Future-then"><a href="#Future-then" class="headerlink" title="Future.then"></a><code>Future.then</code></h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Future.delayed(new Duration(seconds: 2), ()&#123;</span><br><span class="line">    return &quot;hi.world&quot;;</span><br><span class="line">&#125;).then((data)&#123;</span><br><span class="line">    print(data);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<h4 id="Future-catchError"><a href="#Future-catchError" class="headerlink" title="Future.catchError"></a><code>Future.catchError</code></h4><p>如果异步任务发生错误，我们可以在 <code>catchError</code> 中捕获错误</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">Future.delayed(new Duration(seconds: 2), ()&#123;</span><br><span class="line">    return &quot;hi.world&quot;;</span><br><span class="line">&#125;).then((data)&#123;</span><br><span class="line">    print(data);</span><br><span class="line">&#125;).catchError((e)&#123;</span><br><span class="line">    // 执行失败会走到这里</span><br><span class="line">    print(e);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>不是只有 <code>catchError</code> 回调才能捕获错误，<code>then</code> 方法还有一个可选参数 <code>onError</code>，我们也可以用它来捕获异常</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Future.delayed(new Duration(seconds: 2), ()&#123;</span><br><span class="line">    return &quot;hi.world&quot;;</span><br><span class="line">&#125;).then((data)&#123;</span><br><span class="line">    print(data);</span><br><span class="line">&#125;, onError: (e)&#123;</span><br><span class="line">    print(e);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<h4 id="Future-whenComplete"><a href="#Future-whenComplete" class="headerlink" title="Future.whenComplete"></a><code>Future.whenComplete</code></h4><p>有些时候，我们会遇到无论异步任务执行成功或失败都需要做一些事的场景，比如在网络请求前弹出加载对话框，在请求结束后关闭对话框。</p>
<p>这种场景，有两种方法，第一种是分别在 <code>then</code> 或 <code>catch</code> 中关闭一下对话框，第二种就是使用 <code>Future</code> 的 <code>whenComplete</code> 回调</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">Future.delayed(new Duration(seconds: 2), ()&#123;</span><br><span class="line">    return &quot;hi.world&quot;;</span><br><span class="line">&#125;).then((data)&#123;</span><br><span class="line">    // 执行成功会走到这里</span><br><span class="line">    print(data);</span><br><span class="line">&#125;, onError: (e)&#123;</span><br><span class="line">    // 执行失败会走到这里</span><br><span class="line">    print(e);</span><br><span class="line">&#125;).whenComplete(()&#123;</span><br><span class="line">    // 无论成功或失败都会走到这里</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<h4 id="Future-wait"><a href="#Future-wait" class="headerlink" title="Future.wait"></a><code>Future.wait</code></h4><p>它接收一个 <code>Future</code> 数组参数，只有数组中所有 <code>Future</code> 都执行成功后，才会触发 <code>then</code> 的成功回调，只要有一个 <code>Future</code> 执行失败，就会触发错误回调。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">Future.wait([</span><br><span class="line">    // 2秒后返回结果</span><br><span class="line">    Future.delayed(new Duration(seconds: 2), ()&#123;</span><br><span class="line">        return &apos;hello&apos;;</span><br><span class="line">    &#125;),</span><br><span class="line">    // 4秒后返回结果</span><br><span class="line">    Future.delayed(new Duration(seconds:4), ()&#123;</span><br><span class="line">        return &apos; world&apos;;</span><br><span class="line">    &#125;)</span><br><span class="line">]).then((results)&#123;</span><br><span class="line">    print(result[0]+result[1]);</span><br><span class="line">&#125;).catchError((e)&#123;</span><br><span class="line">    print(e);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<h3 id="Async-await"><a href="#Async-await" class="headerlink" title="Async/await"></a><code>Async/await</code></h3><h4 id="回调地狱（Callback-Hell）"><a href="#回调地狱（Callback-Hell）" class="headerlink" title="回调地狱（Callback Hell）"></a>回调地狱（Callback Hell）</h4><p>如果代码中有大量的异步逻辑，并且出现大量异步任务依赖其它异步任务的结果时，必然会出现 <code>Future.then</code> 回调中套回调情况</p>
<p>可以感受一下，如果业务逻辑中由大量异步依赖的情况，将会出现在回调里面套回调的情况，过多的嵌套会导致代码可读性下降以及出错率提高，并且非常难维护，这个问题被形象的称为回调地狱（Callback Hell）</p>
<h4 id="使用-async-await-消除-callback-hell"><a href="#使用-async-await-消除-callback-hell" class="headerlink" title="使用 async/await 消除 callback hell"></a>使用 <code>async/await</code> 消除 callback hell</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">Future&lt;String&gt; login(String userName, String pwd)&#123;</span><br><span class="line">    // 用户登录</span><br><span class="line">&#125;</span><br><span class="line">Future&lt;String&gt; getUserInfo(String id)&#123;</span><br><span class="line">    // 获取用户信息</span><br><span class="line">&#125;</span><br><span class="line">Future saveUserInfo(String userInfo)&#123;</span><br><span class="line">    // 保存用户信息</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">task() async&#123;</span><br><span class="line">    try&#123;</span><br><span class="line">        String id = await login(&apos;alice&apos;, &apos;*****&apos;);</span><br><span class="line">        String userInfo = await getUserInfo(id);</span><br><span class="line">        await saveUserInfo(userInfo);</span><br><span class="line">    &#125;catch(e)&#123;</span><br><span class="line">        // 错误处理</span><br><span class="line">        print(e);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li><p><code>async</code> 用来表示函数是异步的，定义的函数会返回一个 <code>Future</code> 对象，可以使用 then 方法添加回调函数</p>
</li>
<li><p><code>await</code> 后面是一个 <code>Future</code>，表示等待该异步任务完成，异步完成后才会往下走；<code>await</code> 必须出现在 <code>async</code> 函数内部</p>
</li>
<li><p>其实，无论是在 JavaScript 还是 Dart 中，<code>async/await</code> 都只是一个语法糖，编译器或解释器最终都会将其转化为一个 Promise(Future) 的调用链</p>
</li>
</ul>
<h3 id="Stream"><a href="#Stream" class="headerlink" title="Stream"></a><code>Stream</code></h3><p><code>Stream</code> 也是用于接收异步事件数据，和 <code>Future</code> 不同的是，它可以接收多个异步操作的结果（成功或失败）。也就是说，在执行异步任务时，可以通过多次触发成功或失败事件来传递结果数据或错误异常。<code>Stream</code> 常用于会多次读取数据的异步任务场景，如网络内容下载、文件读写等</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">Stream.fromFutures([</span><br><span class="line">    // 1秒后返回结果</span><br><span class="line">    Future.delayed(new Duration(seconds: 1), ()&#123;</span><br><span class="line">        return &apos;hello 1&apos;;</span><br><span class="line">    &#125;),</span><br><span class="line">    // 抛出一个异常</span><br><span class="line">    Future.delayed(new Duration(seconds: 2), ()&#123;</span><br><span class="line">        throw AssertionError(&apos;Error&apos;);</span><br><span class="line">    &#125;),</span><br><span class="line">    // 3秒后返回结果</span><br><span class="line">    Future.delayed(new Duration(seconds: 3), ()&#123;</span><br><span class="line">        return &apos;hello 3&apos;;</span><br><span class="line">    &#125;)</span><br><span class="line">]).listen((data)&#123;</span><br><span class="line">    print(data);</span><br><span class="line">&#125;, onError: (e)&#123;</span><br><span class="line">    print(e.message);</span><br><span class="line">&#125;, onDone: ()&#123;</span><br><span class="line"></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<p>上面的代码依次会输出</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">I/flutter (17666): hello 1</span><br><span class="line">I/flutter (17666): Error</span><br><span class="line">I/flutter (17666): hello 3</span><br></pre></td></tr></table></figure>
      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/11/09/Dart语言简介/" data-id="ck4r400os002nl0w02y5nwt72" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Dart/">Dart</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-Flutter-路由管理" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/11/09/Flutter-路由管理/" class="article-date">
  <time datetime="2019-11-09T07:23:51.000Z" itemprop="datePublished">2019-11-09</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/Flutter/">Flutter</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/11/09/Flutter-路由管理/">flutter-路由管理</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<p>路由（Route）在移动开发中通常指页面（Page），这跟 web 开发中单页应用的 Route 概念意义是相同的，Route 在 Android 中通常指一个 Activity，在 iOS 中指一个 ViewController。所谓路由管理，就是管理页面之间如何跳转，通常也可被称为导航管理。Flutter 中的路由管理和原生开发类似，无论是 Android 还是 iOS，导航管理都会维护一个路由栈，路由入栈（push）操作对应打开一个新页面，路由出栈（pop）操作对应页面关闭操作，而路由管理主要是指如何来管理路由栈</p>
<h2 id="MaterialPageRoute"><a href="#MaterialPageRoute" class="headerlink" title="MaterialPageRoute"></a>MaterialPageRoute</h2><p><code>MaterialPageRoute</code> 继承自 <code>PageRoute</code> 类是一个抽象类，表示占有整个屏幕空间的一个模态路由页面，它还定义了路由构建及切换时过渡动画的相关接口及属性。</p>
<h3 id="MaterialPageRoute的构造函数"><a href="#MaterialPageRoute的构造函数" class="headerlink" title="MaterialPageRoute的构造函数"></a>MaterialPageRoute的构造函数</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">MaterialPageRoute(&#123;</span><br><span class="line">    WidgetBuilder builder,</span><br><span class="line">    RouteSetting setting,</span><br><span class="line">    bool maintainState = true,</span><br><span class="line">    bool fullscreenDialog = false,</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<ul>
<li><p><code>builder</code>：是一个 <code>WidgetBuilder</code> 类型的回调函数，它的作用是构建路由页面的具体内容，返回值是一个 widget。</p>
</li>
<li><p><code>settings</code>：包含路由的配置信息，如路由名称、是否初始路由（首页）</p>
</li>
<li><p><code>maintainState</code>：默认情况下，当入栈一个新路由时，原来的路由仍然会被保存在内容中，如果想在路由没用的时候释放其所占用的所有资源，可以设置 <code>maintainState</code> 为 false</p>
</li>
<li><p><code>fullscreenDialog</code> 表示新的路由页面是否是一个全屏的模态对话框，在iOS中，如果 <code>fullscreenDialog</code> 为 true，新页面将会从屏幕底部滑入（而不是水平方向）</p>
</li>
</ul>
<p>如果想自定义路由切换动画，可以自己继承 <code>PageRoute</code> 来实现</p>
<h2 id="Navigator"><a href="#Navigator" class="headerlink" title="Navigator"></a>Navigator</h2><p><code>Navigator</code> 是一个路由管理的组件，它提供了打开和退出路由页方法。<code>Navigator</code> 通过一个栈来管理活动路由集合。通常当前屏幕显示的页面就是栈顶的路由。<code>Navigator</code> 提供了一系列方法来管理路由栈</p>
<h3 id="Future-push-BuildContext-context-Route-route"><a href="#Future-push-BuildContext-context-Route-route" class="headerlink" title="Future push(BuildContext context, Route route)"></a>Future push(BuildContext context, Route route)</h3><p>将给定的路由入栈（即打开新的页面），返回值是一个 <code>Future</code> 对象，用以接收新路由出栈（即关闭）时的返回数据</p>
<h3 id="bool-pop-BuildContext-context-result"><a href="#bool-pop-BuildContext-context-result" class="headerlink" title="bool pop(BuildContext context, [result])"></a>bool pop(BuildContext context, [result])</h3><p>将栈顶路由出栈，<code>result</code> 为页面关闭时返回给上一个页面的数据</p>
<h3 id="实例方法"><a href="#实例方法" class="headerlink" title="实例方法"></a>实例方法</h3><p><code>Navigator</code> 类中第一个参数为 context 的静态方法都对应一个 <code>Navigator</code> 的实例方法</p>
<p>比如 <code>Navigator.push(BuildContext context, Route route)</code>等价于 <code>Navigator.of(context).push(Route route)</code></p>
<h2 id="路由传值"><a href="#路由传值" class="headerlink" title="路由传值"></a>路由传值</h2><p>我们创建一个 <code>TipRoute</code> 路由，它接受一个提示文本参数，负责将传入它的文本显示在页面上，另外 <code>TipRoute</code> 中我们添加一个“返回”按钮，点击后在返回上一个路由的同时会带上一个返回参数</p>
<p>示例</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/11/09/Flutter-路由管理/" data-id="ck4r400p9003gl0w0su4134d1" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Flutter/">Flutter</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-Flutter-初识篇" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/11/08/Flutter-初识篇/" class="article-date">
  <time datetime="2019-11-08T14:03:38.000Z" itemprop="datePublished">2019-11-08</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/Flutter/">Flutter</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/11/08/Flutter-初识篇/">Flutter-初识篇</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<h2 id="认识-Flutter"><a href="#认识-Flutter" class="headerlink" title="认识 Flutter"></a>认识 Flutter</h2><p>Flutter 是谷歌的移动 UI 框架，可以快速在 IOS 和 Android 上构建高质量的原生用户界面。</p>
<p>Flutter 可以与现有的代码一起工作。在全世界，Flutter 正在被越来越多的开发者和组织使用，并且 Flutter 是完全免费、开源的</p>
<h2 id="终端命令"><a href="#终端命令" class="headerlink" title="终端命令"></a>终端命令</h2><blockquote>
<p><code>flutter run</code></p>
</blockquote>
<p>运行，并且显示虚拟机</p>
<blockquote>
<p><code>r</code></p>
</blockquote>
<p>热更新</p>
<blockquote>
<p><code>p</code></p>
</blockquote>
<ul>
<li><p>第一次按下，显示标尺（表格）</p>
</li>
<li><p>再次按下，标尺消失</p>
</li>
</ul>
<blockquote>
<p><code>o</code></p>
</blockquote>
<ul>
<li><p>如果在 Android 模式下，就会查看 iOS 模式下样式</p>
</li>
<li><p>如果在 iOS 模式下，就会查看 Android 模式下样式</p>
</li>
</ul>
<blockquote>
<p><code>q</code></p>
</blockquote>
<p>退出，虚拟机关闭</p>
<blockquote>
<p><code>R</code></p>
</blockquote>
<p>热重启</p>
<h3 id="热更新的另一种方法"><a href="#热更新的另一种方法" class="headerlink" title="热更新的另一种方法"></a>热更新的另一种方法</h3><p>启动 VSCode 的 Debug，等待启动后，每次想要调试的时候 <code>ctrl+s</code></p>
<h1 id="初始-Flutter-语法"><a href="#初始-Flutter-语法" class="headerlink" title="初始 Flutter 语法"></a>初始 Flutter 语法</h1><h2 id="案例"><a href="#案例" class="headerlink" title="案例"></a>案例</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line">import &apos;package:flutter/material.dart&apos;;</span><br><span class="line"></span><br><span class="line">void main() =&gt; runApp(new MyApp());</span><br><span class="line"></span><br><span class="line">class MyApp extends StatelessWidget &#123;</span><br><span class="line">@override</span><br><span class="line">Widget build(BuildContext context) &#123;</span><br><span class="line">    return new MaterialApp(</span><br><span class="line">    title: &apos;Flutter Demo&apos;,</span><br><span class="line">    theme: new ThemeData(</span><br><span class="line">        primarySwatch: Colors.blue,</span><br><span class="line">    ),</span><br><span class="line">    home: new MyHomePage(title: &apos;Flutter Demo Home Page&apos;),</span><br><span class="line">    );</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">class MyHomePage extends StatefulWidget &#123;</span><br><span class="line">MyHomePage(&#123;Key key, this.title&#125;) : super(key: key);</span><br><span class="line">final String title;</span><br><span class="line"></span><br><span class="line">@override</span><br><span class="line">_MyHomePageState createState() =&gt; new _MyHomePageState();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">class _MyHomePageState extends State&lt;MyHomePage&gt; &#123;</span><br><span class="line">int _counter = 0;</span><br><span class="line"></span><br><span class="line">void _incrementCounter() &#123;</span><br><span class="line">    setState(() &#123;</span><br><span class="line">    _counter++;</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">@override</span><br><span class="line">Widget build(BuildContext context) &#123;</span><br><span class="line">    return new Scaffold(</span><br><span class="line">    appBar: new AppBar(</span><br><span class="line">        title: new Text(widget.title),</span><br><span class="line">    ),</span><br><span class="line">    body: new Center(</span><br><span class="line">        child: new Column(</span><br><span class="line">        mainAxisAlignment: MainAxisAlignment.center,</span><br><span class="line">        children: &lt;Widget&gt;[</span><br><span class="line">            new Text(</span><br><span class="line">            &apos;You have pushed the button this many times:&apos;,</span><br><span class="line">            ),</span><br><span class="line">            new Text(</span><br><span class="line">            &apos;$_counter&apos;,</span><br><span class="line">            style: Theme.of(context).textTheme.display1,</span><br><span class="line">            ),</span><br><span class="line">        ],</span><br><span class="line">        ),</span><br><span class="line">    ),</span><br><span class="line">    floatingActionButton: new FloatingActionButton(</span><br><span class="line">        onPressed: _incrementCounter,</span><br><span class="line">        tooltip: &apos;Increment&apos;,</span><br><span class="line">        child: new Icon(Icons.add),</span><br><span class="line">    ), // This trailing comma makes auto-formatting nicer for build methods.</span><br><span class="line">    );</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="导入包"><a href="#导入包" class="headerlink" title="导入包"></a>导入包</h2><blockquote>
<p><code>import &#39;package:flutter/material.dart&#39;;</code></p>
</blockquote>
<p>此行代码作用是导入了 Material UI 组件库。Material 是一种标准的移动端和 web 端的视觉设计语言，Flutter 默认提供了一套丰富的 Material 风格的 UI 组件</p>
<h2 id="应用入口"><a href="#应用入口" class="headerlink" title="应用入口"></a>应用入口</h2><blockquote>
<p><code>void main() =&gt; runApp(MyApp());</code></p>
</blockquote>
<p>与 C/C++、java 类似，Flutter 应用中 <code>main</code> 函数为应用程序的入口。<code>main</code> 函数中调用了 <code>runApp</code> 方法，它的功能是启动 Flutter 应用。<code>runApp</code> 它接受一个 <code>Widget</code> 参数，在本示例中它是一个 <code>MyApp</code> 对象，<code>MyApp()</code> 是 Flutter 应用的根组件</p>
<h2 id="应用结构"><a href="#应用结构" class="headerlink" title="应用结构"></a>应用结构</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">class MyApp extends StatelessWidget &#123;</span><br><span class="line">    @override</span><br><span class="line">    Widget build(BuildContext context) &#123;</span><br><span class="line">        return new MaterialApp(</span><br><span class="line">            //应用名称  </span><br><span class="line">            title: &apos;Flutter Demo&apos;, </span><br><span class="line">            theme: new ThemeData(</span><br><span class="line">                //蓝色主题  </span><br><span class="line">                primarySwatch: Colors.blue,</span><br><span class="line">            ),</span><br><span class="line">            //应用首页路由  </span><br><span class="line">            home: new MyHomePage(title: &apos;Flutter Demo Home Page&apos;),</span><br><span class="line">        );</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li><p><code>MyApp</code> 类代表 <code>Flutter</code> 应用，它继承了 <code>StatelessWidget</code> 类，这也就意味着应用本身也是一个 widget</p>
</li>
<li><p>Flutter 在构建页面时，会调用组件的 <code>build</code> 方法，widget 的主要工作是提供一个 build() 方法来描述如何构建 UI 界面（通常是通过组合、拼装其它基础 widget）</p>
</li>
<li><p><code>MaterialApp</code> 是 Material 库中提供的 Flutter APP 框架，通过它可以设置应用的名称、主题、语言、首页及路由列表。<code>MaterialApp</code> 也是一个 widget</p>
</li>
<li><p><code>Scaffold</code> 是 Material 库中提供的页面脚手架，它包含导航栏和 Body 以及 <code>FloatingActionButton</code> </p>
</li>
</ul>
<h2 id="StatefulWidget"><a href="#StatefulWidget" class="headerlink" title="StatefulWidget"></a>StatefulWidget</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">class MyHomePage extends StatefulWidget &#123;</span><br><span class="line">    MyHomePage(&#123;Key key, this.title&#125;) : super(key: key);</span><br><span class="line">    final String title;</span><br><span class="line">    @override</span><br><span class="line">    _MyHomePageState createState() =&gt; new _MyHomePageState();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">class _MyHomePageState extends State&lt;MyHomePage&gt; &#123;</span><br><span class="line">    ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>MyHomePage</code> 是 Flutter 应用的首页，它继承自 <code>StatefulWidget</code> 类，表示它是一个有状态的组件（Stateful widget）。</p>
<h3 id="有状态组件-Stateful-widget-和无状态组件-Stateless-widget-的不同"><a href="#有状态组件-Stateful-widget-和无状态组件-Stateless-widget-的不同" class="headerlink" title="有状态组件(Stateful widget)和无状态组件(Stateless widget)的不同"></a>有状态组件(Stateful widget)和无状态组件(Stateless widget)的不同</h3><ol>
<li><p>Stateful widget 可以拥有状态，这些状态在 widget 生命周期中是可以变的，而 Stateless widget 是不可变的</p>
</li>
<li><p>Stateful widget 至少由两个类组成</p>
<ul>
<li><p>一个 <code>StatefulWidget</code> 类</p>
</li>
<li><p>一个 <code>State</code> 类；<code>StatefulWidget</code> 类本身是不变的，但是 <code>State</code> 类中持有的状态在 widget 生命周期中可能会发生变化</p>
</li>
</ul>
</li>
</ol>
<p><code>_MyHomePageState</code> 类是 <code>MyHomePage</code> 类对应的状态类</p>
<h2 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"> Widget build(BuildContext context) &#123;</span><br><span class="line">    return new Scaffold(</span><br><span class="line">    appBar: new AppBar(</span><br><span class="line">        title: new Text(widget.title),</span><br><span class="line">    ),</span><br><span class="line">    body: new Center(</span><br><span class="line">        child: new Column(</span><br><span class="line">        mainAxisAlignment: MainAxisAlignment.center,</span><br><span class="line">        children: &lt;Widget&gt;[</span><br><span class="line">            new Text(</span><br><span class="line">            &apos;You have pushed the button this many times:&apos;,</span><br><span class="line">            ),</span><br><span class="line">            new Text(</span><br><span class="line">            &apos;$_counter&apos;,</span><br><span class="line">            style: Theme.of(context).textTheme.display1,</span><br><span class="line">            ),</span><br><span class="line">        ],</span><br><span class="line">        ),</span><br><span class="line">    ),</span><br><span class="line">    floatingActionButton: new FloatingActionButton(</span><br><span class="line">        onPressed: _incrementCounter,</span><br><span class="line">        tooltip: &apos;Increment&apos;,</span><br><span class="line">        child: new Icon(Icons.add),</span><br><span class="line">    ),</span><br><span class="line">    );</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li><p><code>Scaffold</code> 是 Material 组件库中提供的一个组件，它提供了默认的导航栏、标题和包含主屏幕 widget 树（后同“组件树”或“部件树”）的 <code>body</code> 属性</p>
</li>
<li><p><code>body</code> 的组件树中包含了一个 <code>Center</code> 组件，<code>Center</code> 可以将其子组件树对齐到屏幕中心。此例中，<code>Center</code> 子组件是一个 <code>Column</code> 组件，<code>Column</code> 的作用是将其所有子组件沿屏幕垂直方向依次排列；此例中 <code>Column</code> 子组件是两个 <code>Text</code>，第一个 <code>Text</code> 显示固定文本，第二个 <code>Text</code> 显示 <code>_counter</code> 状态的数值</p>
</li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/11/08/Flutter-初识篇/" data-id="ck4r400p8003el0w0nid9dfmq" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Flutter/">Flutter</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-TypeScript核心语法" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/11/07/TypeScript核心语法/" class="article-date">
  <time datetime="2019-11-07T10:29:03.000Z" itemprop="datePublished">2019-11-07</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/TypeScript/">TypeScript</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/11/07/TypeScript核心语法/">TypeScript核心语法</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<h1 id="基本数据类型"><a href="#基本数据类型" class="headerlink" title="基本数据类型"></a>基本数据类型</h1><ol>
<li><p>布尔值：boolean</p>
</li>
<li><p>数值：number</p>
</li>
<li><p>字符串：string</p>
</li>
<li><p>特别的类型：void / undefined / null</p>
</li>
</ol>
<p><code>undefined</code> 和 <code>null</code> 是所有类型的子类型</p>
<h2 id="任意值-any"><a href="#任意值-any" class="headerlink" title="任意值(any)"></a>任意值(any)</h2><p>表示允许赋值为任意类型</p>
<ul>
<li><p><code>any</code> 类型的变量可以赋值任意类型的值</p>
</li>
<li><p><code>any</code> 类型的变量可以使用任意属性和方法</p>
</li>
<li><p>定义不指定类型的变量，且定义时不赋值，相当于类型的 <code>any</code></p>
</li>
</ul>
<h2 id="类型推论"><a href="#类型推论" class="headerlink" title="类型推论"></a>类型推论</h2><p>TypeScript 会在没有明确的指定类型的时候推测出一个类型</p>
<ul>
<li><p>定义变量时赋值了，推断为对应的类型</p>
</li>
<li><p>定义变量时没有赋值，推断为 <code>any</code> 类型</p>
</li>
</ul>
<h2 id="联合类型（Union-Types）"><a href="#联合类型（Union-Types）" class="headerlink" title="联合类型（Union Types）"></a>联合类型（Union Types）</h2><p>表示取值可以为多种类型中的一种</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">let c1: number | string = 3;</span><br><span class="line">c1 = &quot;123&quot;;</span><br></pre></td></tr></table></figure>

<h2 id="类型断言（Type-Assertion）"><a href="#类型断言（Type-Assertion）" class="headerlink" title="类型断言（Type Assertion）"></a>类型断言（Type Assertion）</h2><p>可以用来手动指定一个值的类型</p>
<h3 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h3><blockquote>
<p>&lt;类型&gt;值</p>
</blockquote>
<blockquote>
<p>值 as 类型</p>
</blockquote>
<p>注意：tsx中只能用这种方式</p>
<h2 id="接口（Interfaces）"><a href="#接口（Interfaces）" class="headerlink" title="接口（Interfaces）"></a>接口（Interfaces）</h2><p>在 TypeScript 中，我们使用接口来定义对象的类型</p>
<ul>
<li><p>接口：在面向对象的语言中，是 n 个行为的抽象/描述，但没有实现，由类去实现</p>
</li>
<li><p>在 TS 中，接口也可以包含状态的描述</p>
</li>
<li><p>只读属性： reasonly</p>
</li>
<li><p>可选属性：?</p>
</li>
</ul>
<p>样例：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">interface IPerson &#123;</span><br><span class="line">    readonly id: number;</span><br><span class="line">    name: string;</span><br><span class="line">    age: number;</span><br><span class="line">    sex?: string;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">const p: IPerson=&#123;</span><br><span class="line">    id: 1,</span><br><span class="line">    name: &apos;demo&apos;,</span><br><span class="line">    age: 12,</span><br><span class="line">    sex: &apos;女&apos;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">const p2: IPerson = &#123;</span><br><span class="line">    id: 2,</span><br><span class="line">    name: &apos;demo2&apos;,</span><br><span class="line">    age: 13</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="数组类型"><a href="#数组类型" class="headerlink" title="数组类型"></a>数组类型</h2><h3 id="方式一"><a href="#方式一" class="headerlink" title="方式一"></a>方式一</h3><blockquote>
<p><code>number[]</code></p>
</blockquote>
<h3 id="方式二（泛型）"><a href="#方式二（泛型）" class="headerlink" title="方式二（泛型）"></a>方式二（泛型）</h3><blockquote>
<p><code>Array&lt;number&gt;</code></p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 使用方式一定义字符串数组类型变量 --&gt;</span><br><span class="line">const names: string[] = [&apos;a&apos;, &apos;b&apos;, &apos;c&apos;]</span><br><span class="line"></span><br><span class="line">&lt;!-- 使用方式二定义字符串数组类型变量 --&gt;</span><br><span class="line">const names: Array&lt;string&gt; = [&apos;a&apos;, &apos;b&apos;, &apos;c&apos;]</span><br><span class="line"></span><br><span class="line">&lt;!-- 定义任意类型数组类型变量 --&gt;</span><br><span class="line">const arr: any[] = [&apos;b&apos;, 1, true]</span><br></pre></td></tr></table></figure>

<h2 id="元组"><a href="#元组" class="headerlink" title="元组"></a>元组</h2><p>可包含多种类型元素的数组</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 定义元组 --&gt;</span><br><span class="line">let person: [string, number] = [&apos;tom&apos;, 12]</span><br></pre></td></tr></table></figure>

<p>当添加越界的元素时，它的类型会被限制为元组中每个类型的联合类型（不能为联合类型之外的其他类型）</p>
<h2 id="函数的类型"><a href="#函数的类型" class="headerlink" title="函数的类型"></a>函数的类型</h2><h3 id="函数声明"><a href="#函数声明" class="headerlink" title="函数声明"></a>函数声明</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">function fn1(x: string, y: number): number &#123;</span><br><span class="line">    return 2;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="可选参数"><a href="#可选参数" class="headerlink" title="可选参数"></a>可选参数</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">const a= function fn1(x: string, y?: number): number &#123;</span><br><span class="line">    return 2;</span><br><span class="line">&#125;</span><br><span class="line">console.log(a);</span><br></pre></td></tr></table></figure>

<h3 id="形参默认值"><a href="#形参默认值" class="headerlink" title="形参默认值"></a>形参默认值</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">const a = function fn1(x: string, y: number = 3): number &#123;</span><br><span class="line">    retu</span><br></pre></td></tr></table></figure>

<h3 id="剩余参数"><a href="#剩余参数" class="headerlink" title="剩余参数"></a>剩余参数</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">const a = function fn1(x: string, ...args: any[]) &#123;</span><br><span class="line">    return args;</span><br><span class="line">&#125;</span><br><span class="line">console.log(a(&apos;a&apos;, 1, &quot;2&quot;, &quot;jdsa&quot;, true));</span><br></pre></td></tr></table></figure>

<h2 id="声明文件"><a href="#声明文件" class="headerlink" title="声明文件"></a>声明文件</h2><p>当使用第三方库时，我们需要引用它的声明文件，才能获得对应的代码补全、接口提示等功能</p>
<h3 id="声明语句"><a href="#声明语句" class="headerlink" title="声明语句"></a>声明语句</h3><p>如果需要 <code>TypeScript</code> 对新的语法进行检查，需要加载对应的类型说明代码</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">declare var jQuery: (selector: string) =&gt; any;</span><br></pre></td></tr></table></figure>

<h3 id="声明文件-1"><a href="#声明文件-1" class="headerlink" title="声明文件"></a>声明文件</h3><p>把声明语句放在一个单独的文件（jQuery.d.ts）中，<code>ts</code> 会自动解析到项目中所有声明文件</p>
<h3 id="下载声明文件"><a href="#下载声明文件" class="headerlink" title="下载声明文件"></a>下载声明文件</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install @types/jquery --save-dev</span><br></pre></td></tr></table></figure>

<h2 id="枚举（Enum）"><a href="#枚举（Enum）" class="headerlink" title="枚举（Enum）"></a>枚举（Enum）</h2><p>用于取值被限定在一定范围内的场景，比如一周只能有七天，颜色限定为红绿蓝等。</p>
<p>枚举使用 enum 关键字来定义</p>
<h2 id="类（class）"><a href="#类（class）" class="headerlink" title="类（class）"></a>类（class）</h2><h3 id="访问修饰符"><a href="#访问修饰符" class="headerlink" title="访问修饰符"></a>访问修饰符</h3><p>public：任何地方都可见，默认是 public</p>
<p>private：只在类内部可见</p>
<p>protected：类内部或子类中可见</p>
<h3 id="readonly"><a href="#readonly" class="headerlink" title="readonly"></a>readonly</h3><p>只能通过构造方法赋值一次</p>
<h3 id="抽象类（abstract）"><a href="#抽象类（abstract）" class="headerlink" title="抽象类（abstract）"></a>抽象类（abstract）</h3><p>可以包含抽象方法</p>
<p>不可以有实例</p>
<h3 id="抽象类与实现类的区别"><a href="#抽象类与实现类的区别" class="headerlink" title="抽象类与实现类的区别"></a>抽象类与实现类的区别</h3><ul>
<li><p>抽象方法：有abstract / 没有方法体 / 不能创建实例</p>
</li>
<li><p>实现方法：没有abstract / 有方法体 / 可以创建实例</p>
</li>
</ul>
<h2 id="接口与类"><a href="#接口与类" class="headerlink" title="接口与类"></a>接口与类</h2><ul>
<li><p>对 <strong>对象的形状（shape）</strong> 进行描述</p>
</li>
<li><p>对类的一部分行为进行抽象</p>
</li>
<li><p>父接口可以有多个，但父类只能有一个：多实现，单继承</p>
</li>
<li><p>一个类可以实现一个接口</p>
</li>
<li><p>一个类可以继承于另一个类</p>
</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">interface Light&#123;</span><br><span class="line">    lightOn(): void;</span><br><span class="line">    lightOff(): void;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&lt;!-- 类实现接口 --&gt;</span><br><span class="line">class Car implements Light &#123;</span><br><span class="line">    lightOn()&#123;</span><br><span class="line">        console.log(&apos;Car light on&apos;);</span><br><span class="line">    &#125;</span><br><span class="line">    lightOff()&#123;</span><br><span class="line">        console.log(&apos;Car light off&apos;);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="泛型"><a href="#泛型" class="headerlink" title="泛型"></a>泛型</h2><p>泛型是指在定义函数、接口或类的时候，不预先指定具体的类型，而在使用的时候再指定类型的一种特性</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">function createArray&lt;T&gt;(length: number, value: T): Array&lt;T&gt; &#123;</span><br><span class="line">    let result: Array&lt;T&gt; = [];</span><br><span class="line">    for (let i = 0; i &lt; length; i++) &#123;</span><br><span class="line">        result[i] = value;</span><br><span class="line">    &#125;</span><br><span class="line">    return result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">createArray&lt;string&gt;(3, &apos;x&apos;)</span><br></pre></td></tr></table></figure>

<h1 id="使用-react-cli-创建-react-ts-项目"><a href="#使用-react-cli-创建-react-ts-项目" class="headerlink" title="使用 react-cli 创建 react-ts 项目"></a>使用 react-cli 创建 react-ts 项目</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">create-react-app react-ts --typescript</span><br></pre></td></tr></table></figure>
      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/11/07/TypeScript核心语法/" data-id="ck4r400rw008kl0w06tnu7qdb" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/TypeScript/">TypeScript</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-redux异步编程" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/11/04/redux异步编程/" class="article-date">
  <time datetime="2019-11-04T08:52:07.000Z" itemprop="datePublished">2019-11-04</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/React/">React</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/11/04/redux异步编程/">redux异步编程</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<h2 id="下载-redux-插件（异步中间件）"><a href="#下载-redux-插件（异步中间件）" class="headerlink" title="下载 redux 插件（异步中间件）"></a>下载 redux 插件（异步中间件）</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save redux-thunk</span><br></pre></td></tr></table></figure>

<h2 id="编码"><a href="#编码" class="headerlink" title="编码"></a>编码</h2><h3 id="index-js"><a href="#index-js" class="headerlink" title="index.js"></a><code>index.js</code></h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">import &#123;createStore, applyMiddleware&#125; from &apos;redux&apos;</span><br><span class="line">import thunk from &apos;redux-thunk&apos;</span><br><span class="line"></span><br><span class="line">// 根据counter函数创建store对象</span><br><span class="line">const store = createStore(</span><br><span class="line">    counter,</span><br><span class="line">    applyMiddleware(thunk) // 应用上异步中间件</span><br><span class="line">)</span><br></pre></td></tr></table></figure>

<h3 id="action-js"><a href="#action-js" class="headerlink" title="action.js"></a><code>action.js</code></h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">// 异步action</span><br><span class="line">// 如果想返回一个函数，必须应用上异步中间件</span><br><span class="line">export const incrementAsync = (number) =&gt; &#123;</span><br><span class="line">    return dispatch =&gt; &#123;</span><br><span class="line">        // 异步代码</span><br><span class="line">        setTimeout(() =&gt; &#123;</span><br><span class="line">            // 一秒之后才去分发一个增加的action</span><br><span class="line">            dispatch(increment(number))</span><br><span class="line">        &#125;, 1000)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="使用-redux-调试工具"><a href="#使用-redux-调试工具" class="headerlink" title="使用 redux 调试工具"></a>使用 redux 调试工具</h2><h3 id="安装-Chrome-浏览器插件"><a href="#安装-Chrome-浏览器插件" class="headerlink" title="安装 Chrome 浏览器插件"></a>安装 Chrome 浏览器插件</h3><blockquote>
<p>redux-devtools2_15_1.crx</p>
</blockquote>
<h3 id="下载工具依赖包"><a href="#下载工具依赖包" class="headerlink" title="下载工具依赖包"></a>下载工具依赖包</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save-dev redux-devtools-extension</span><br></pre></td></tr></table></figure>

<h3 id="编码-1"><a href="#编码-1" class="headerlink" title="编码"></a>编码</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">import &#123; composeWithDevTools &#125; from &apos;redux-devtools-extension&apos;</span><br><span class="line"></span><br><span class="line">//生成store对象</span><br><span class="line">const store = createStore(counter,</span><br><span class="line">    composeWithDevTools(applyMiddleware(thunk)) // 应用上异步中间件</span><br><span class="line">); // 内部会第一次调用reducer函数，得到初始state</span><br></pre></td></tr></table></figure>
      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/11/04/redux异步编程/" data-id="ck4r400t900ayl0w0lf70yvt7" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/React/">React</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-react-redux" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/11/03/react-redux/" class="article-date">
  <time datetime="2019-11-03T10:29:29.000Z" itemprop="datePublished">2019-11-03</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/React/">React</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/11/03/react-redux/">react-redux</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<h2 id="理解"><a href="#理解" class="headerlink" title="理解"></a>理解</h2><ol>
<li><p>一个 react 插件库</p>
</li>
<li><p>专门用来简化 react 应用中使用 redux</p>
</li>
</ol>
<h2 id="React-Redux-将所有组件分成两大类"><a href="#React-Redux-将所有组件分成两大类" class="headerlink" title="React-Redux 将所有组件分成两大类"></a>React-Redux 将所有组件分成两大类</h2><h3 id="UI-组件"><a href="#UI-组件" class="headerlink" title="UI 组件"></a>UI 组件</h3><ul>
<li><p>只负责 UI 的呈现，不带任何业务逻辑</p>
</li>
<li><p>通过 props 接收数据（一般数据和函数）</p>
</li>
<li><p>不使用任何 Redux 的 API</p>
</li>
<li><p>一般保存在 components 文件夹下</p>
</li>
</ul>
<h3 id="容器组件"><a href="#容器组件" class="headerlink" title="容器组件"></a>容器组件</h3><ul>
<li><p>负责管理数据和业务逻辑，不负责 UI 的呈现</p>
</li>
<li><p>使用 Redux 的 API</p>
</li>
<li><p>一般保存在 containers 文件夹下</p>
</li>
</ul>
<h2 id="相关-API"><a href="#相关-API" class="headerlink" title="相关 API"></a>相关 API</h2><h3 id="Provider"><a href="#Provider" class="headerlink" title="Provider"></a>Provider</h3><p>让所有组件都可以得到 state 数据</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;Provider store=&#123;store&#125; &gt;</span><br><span class="line">    &lt;App /&gt;</span><br><span class="line">&lt;/Provider&gt;</span><br></pre></td></tr></table></figure>

<h3 id="connect"><a href="#connect" class="headerlink" title="connect()"></a>connect()</h3><p>用于包装 UI 组件生成容器组件</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">import &#123; connect &#125; from &apos;react-redux&apos;</span><br><span class="line"></span><br><span class="line">export default connect(</span><br><span class="line">    mapStateToprops()</span><br><span class="line">    mapDispatchToprops()</span><br><span class="line">)(component)</span><br></pre></td></tr></table></figure>

<h3 id="mapStateToprops"><a href="#mapStateToprops" class="headerlink" title="mapStateToprops()"></a>mapStateToprops()</h3><p>将外部的数据（即 state 对象）转换为 UI 组件的标签属性</p>
<h3 id="mapDispatchToProps"><a href="#mapDispatchToProps" class="headerlink" title="mapDispatchToProps"></a>mapDispatchToProps</h3><p>将分发 action 的函数转换为 UI 组件的标签属性</p>
<p>简洁语法可以直接指定为 actins 对象或包含多个 action 方法的对象</p>
<h2 id="使用-react-redux"><a href="#使用-react-redux" class="headerlink" title="使用 react-redux"></a>使用 react-redux</h2><h3 id="下载依赖包"><a href="#下载依赖包" class="headerlink" title="下载依赖包"></a>下载依赖包</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save react-redux</span><br></pre></td></tr></table></figure>

<h2 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h2><ol>
<li><p>redux 默认是不能进行异步处理的</p>
</li>
<li><p>应用中又需要在 redux 中执行异步任务(ajax, 定时器)</p>
</li>
</ol>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/11/03/react-redux/" data-id="ck4r400t100aml0w0x9ujrrwc" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/React/">React</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-redux" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/11/02/redux/" class="article-date">
  <time datetime="2019-11-02T03:13:29.000Z" itemprop="datePublished">2019-11-02</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/React/">React</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/11/02/redux/">redux</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<h2 id="redux-是什么"><a href="#redux-是什么" class="headerlink" title="redux 是什么"></a>redux 是什么</h2><ol>
<li><p>redux 是一个独立专门用于做状态管理的 JS 库（不是 react 插件库）</p>
</li>
<li><p>它可以用在 react，angular，Vue 等项目中，但基本与 react 配合使用</p>
</li>
<li><p>作用：集中式管理 react 应用中多个组件共享的状态</p>
</li>
</ol>
<h3 id="谨记"><a href="#谨记" class="headerlink" title="谨记"></a>谨记</h3><p>建议在多个组件中共享的 state 才用 redux</p>
<h2 id="下载依赖包"><a href="#下载依赖包" class="headerlink" title="下载依赖包"></a>下载依赖包</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save redux</span><br></pre></td></tr></table></figure>

<h1 id="redux-的核心-API"><a href="#redux-的核心-API" class="headerlink" title="redux 的核心 API"></a>redux 的核心 API</h1><h2 id="createStore"><a href="#createStore" class="headerlink" title="createStore()"></a>createStore()</h2><h3 id="作用"><a href="#作用" class="headerlink" title="作用"></a>作用</h3><p>创建包含指定 reducer 的 store 对象</p>
<h3 id="编码"><a href="#编码" class="headerlink" title="编码"></a>编码</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">import &#123;createStore&#125; from &apos;redux&apos;</span><br><span class="line">import counter from &apos;./reducers/counter&apos;</span><br><span class="line">const store = createStore(counter)</span><br></pre></td></tr></table></figure>

<h2 id="store-对象"><a href="#store-对象" class="headerlink" title="store 对象"></a>store 对象</h2><h3 id="作用-1"><a href="#作用-1" class="headerlink" title="作用"></a>作用</h3><p>redux 库最核心的管理对象</p>
<h3 id="它内部维护着："><a href="#它内部维护着：" class="headerlink" title="它内部维护着："></a>它内部维护着：</h3><ul>
<li><p>state</p>
</li>
<li><p>reducer</p>
</li>
</ul>
<h3 id="核心方法："><a href="#核心方法：" class="headerlink" title="核心方法："></a>核心方法：</h3><ul>
<li><p>getState()</p>
</li>
<li><p>dispatch(action)：更新 state 状态</p>
</li>
<li><p>subscribe(listener)：订阅监听（store中的状态变化了，就会自动调用进行重绘）</p>
</li>
</ul>
<h3 id="编码-1"><a href="#编码-1" class="headerlink" title="编码"></a>编码</h3><ul>
<li><p>store.getState()</p>
</li>
<li><p>store.dispatch({type: ‘INCREMENT’, number})</p>
</li>
<li><p>store.subscribe(render)</p>
</li>
</ul>
<h2 id="applyMiddleware"><a href="#applyMiddleware" class="headerlink" title="applyMiddleware()"></a>applyMiddleware()</h2><h3 id="作用-2"><a href="#作用-2" class="headerlink" title="作用"></a>作用</h3><p>应用上基于 redux 的中间件（插件库）</p>
<h3 id="编码-2"><a href="#编码-2" class="headerlink" title="编码"></a>编码</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">import &#123;createStore, applyMiddleware&#125; from &apos;redux&apos;</span><br><span class="line">import thunk from &apos;redux-thunk&apos; // redux 异步中间件</span><br><span class="line">const store = createStore(</span><br><span class="line">    counter,</span><br><span class="line">    applyMiddleware(thunk) // 应用上异步中间件</span><br><span class="line">)</span><br></pre></td></tr></table></figure>

<h2 id="combineReducers"><a href="#combineReducers" class="headerlink" title="combineReducers()"></a>combineReducers()</h2><h3 id="作用："><a href="#作用：" class="headerlink" title="作用："></a>作用：</h3><p>合并多个 reducer 函数</p>
<h3 id="编码："><a href="#编码：" class="headerlink" title="编码："></a>编码：</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">export default combineReducers(&#123;</span><br><span class="line">    user,</span><br><span class="line">    chatUser,</span><br><span class="line">    chat</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<h1 id="redux-的三个核心概念"><a href="#redux-的三个核心概念" class="headerlink" title="redux 的三个核心概念"></a>redux 的三个核心概念</h1><h2 id="action"><a href="#action" class="headerlink" title="action"></a>action</h2><ul>
<li><p>标识要执行行为的对象</p>
</li>
<li><p>包含两个方面的属性</p>
<ul>
<li><p>type: 标识属性，值为字符串，唯一，必要属性</p>
</li>
<li><p>xxx: 数据属性，值类型任意，可选属性</p>
</li>
</ul>
</li>
<li><p>Action Creator（创建 Action 的工厂函数）</p>
  <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">const increment = (number) =&gt; (&#123;type: &apos;INCREMENT&apos;, data: number&#125;)</span><br></pre></td></tr></table></figure>

</li>
</ul>
<h2 id="reducer"><a href="#reducer" class="headerlink" title="reducer"></a>reducer</h2><ul>
<li><p>根据老的 state 和 action，产生新的 state 的纯函数</p>
</li>
<li><p>样例：</p>
  <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">export default function counter(state = 0, action)&#123;</span><br><span class="line">    switch(action.type)&#123;</span><br><span class="line">        case &apos;INCREMENT&apos;:</span><br><span class="line">            return state + action.data</span><br><span class="line">        case &apos;DECREMENT&apos;</span><br><span class="line">            return state - action.data</span><br><span class="line">        default:</span><br><span class="line">            return state</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>注意：返回一个新的状态，不要改变原来的状态</p>
</li>
</ul>
<h2 id="store"><a href="#store" class="headerlink" title="store"></a>store</h2><ul>
<li><p>将 state，action 与 reducer 联系在一起的对象</p>
</li>
<li><p>如何得到此对象？</p>
</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">import &#123;createStore&#125; from &apos;redux&apos;</span><br><span class="line">import reducer from &apos;./reducers&apos;</span><br><span class="line">const store = createStore(reducer)</span><br></pre></td></tr></table></figure>

<ul>
<li><p>此对象的功能？</p>
<ul>
<li><p>getState(): 得到 state</p>
</li>
<li><p>dispatch(): 分发 action，触发 reducer 调用。产生新的 state</p>
</li>
<li><p>subscribe(listener): 注册监听，当产生了新的 state 时，自动调用</p>
</li>
</ul>
</li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/11/02/redux/" data-id="ck4r400t500atl0w00xblt444" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/React/">React</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-React-router" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/10/30/React-router/" class="article-date">
  <time datetime="2019-10-30T10:32:00.000Z" itemprop="datePublished">2019-10-30</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/React/">React</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/10/30/React-router/">React-router</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<h2 id="react-router-的理解"><a href="#react-router-的理解" class="headerlink" title="react-router 的理解"></a>react-router 的理解</h2><ol>
<li><p>react 的一个插件库</p>
</li>
<li><p>专门用来实现一个 SPA 应用</p>
</li>
<li><p>基于 react 的项目基本都会用到此库</p>
</li>
</ol>
<h2 id="SPA-的理解"><a href="#SPA-的理解" class="headerlink" title="SPA 的理解"></a>SPA 的理解</h2><ol>
<li><p>单页 Web 应用（single page web application）</p>
</li>
<li><p>整个应用只有一个完整的页面</p>
</li>
<li><p>点击页面中的链接不会刷新页面，本身也不会向服务器发请求</p>
</li>
<li><p>当点击链接时，只会做页面的局部更新</p>
</li>
<li><p>数据都需要通过 ajax 请求获取，并在前端异步展现</p>
</li>
</ol>
<h2 id="路由的理解"><a href="#路由的理解" class="headerlink" title="路由的理解"></a>路由的理解</h2><h3 id="什么是路由"><a href="#什么是路由" class="headerlink" title="什么是路由"></a>什么是路由</h3><ul>
<li><p>一个路由就是一个映射关系(key: value)</p>
</li>
<li><p>key 为路由路径，value 可能是 function/component</p>
</li>
</ul>
<h3 id="路由分类"><a href="#路由分类" class="headerlink" title="路由分类"></a>路由分类</h3><ul>
<li><p>后台路由：node 服务器端路由，value 是function，用来处理客户端提交的请求并返回一个响应数据</p>
</li>
<li><p>前台路由：浏览器端路由，value 是 component，当请求的是路由 path 时，浏览器端前没有发送 HTTP 请求，但界面会更新显示对应的组件</p>
</li>
</ul>
<h3 id="后台路由"><a href="#后台路由" class="headerlink" title="后台路由"></a>后台路由</h3><ul>
<li><p>注册路由：router.get(path, function(req, res))</p>
</li>
<li><p>当 node 接收到一个请求时，根据请求路径找到匹配的路由，调用路由中的函数来处理请求，返回响应数据</p>
</li>
</ul>
<h3 id="前端路由"><a href="#前端路由" class="headerlink" title="前端路由"></a>前端路由</h3><ul>
<li><p>注册路由：<code>&lt;Route path=&#39;/about&#39; component={About}&gt;</code></p>
</li>
<li><p>当浏览器的 hash 变为 #about 时，当前路由组件就会变成 About 组件</p>
</li>
</ul>
<h2 id="react-router-相关-API"><a href="#react-router-相关-API" class="headerlink" title="react-router 相关 API"></a>react-router 相关 API</h2><h3 id="组件"><a href="#组件" class="headerlink" title="组件"></a>组件</h3><ul>
<li><p><code>&lt;BrowerRouter</code></p>
</li>
<li><p><code>&lt;HashRouter&gt;</code></p>
</li>
<li><p><code>&lt;Router&gt;</code></p>
</li>
<li><p><code>&lt;Redirect&gt;</code>：默认选中路由</p>
</li>
<li><p><code>&lt;Link&gt;</code></p>
</li>
<li><p><code>&lt;NavLink&gt;</code></p>
</li>
<li><p><code>&lt;Switch&gt;</code>：其中的<code>&lt;Route&gt;</code>在路径相同的情况下，只匹配第一个，这个可以避免重复匹配</p>
</li>
</ul>
<h3 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h3><ul>
<li><p>history 对象</p>
</li>
<li><p>match 对象</p>
</li>
<li><p>withRouter 函数</p>
</li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/10/30/React-router/" data-id="ck4r400rl007wl0w0cmx5h6gu" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/React/">React</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-React生命周期" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/10/29/React生命周期/" class="article-date">
  <time datetime="2019-10-29T11:24:09.000Z" itemprop="datePublished">2019-10-29</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/React/">React</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/10/29/React生命周期/">React生命周期</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <hr>
<h2 id="React-为每个状态都提供了钩子-hook-函数"><a href="#React-为每个状态都提供了钩子-hook-函数" class="headerlink" title="React 为每个状态都提供了钩子(hook)函数"></a>React 为每个状态都提供了钩子(hook)函数</h2><ul>
<li><p>componentWillMount()</p>
</li>
<li><p>componentDidMount()</p>
</li>
<li><p>componentWillUpdate()</p>
</li>
<li><p>componentDidUpdate()</p>
</li>
<li><p>componentWillUnmount()</p>
</li>
</ul>
<h2 id="生命周期流程"><a href="#生命周期流程" class="headerlink" title="生命周期流程"></a>生命周期流程</h2><h3 id="第一次渲染显示：ReactDOM-render"><a href="#第一次渲染显示：ReactDOM-render" class="headerlink" title="第一次渲染显示：ReactDOM.render()"></a>第一次渲染显示：ReactDOM.render()</h3><ol>
<li><p>constructor()：创建对象初始化 state</p>
</li>
<li><p>componentWillMount()：将要插入回调</p>
</li>
<li><p>render()：用于插入虚拟 DOM 回调</p>
</li>
<li><p>componentDidMount()：已经插入回调</p>
</li>
</ol>
<h3 id="每次更新-state-this-setState"><a href="#每次更新-state-this-setState" class="headerlink" title="每次更新 state: this.setState()"></a>每次更新 state: this.setState()</h3><ol>
<li><p>componentWillUpdate()：将要更新回调</p>
</li>
<li><p>render()：更新(重新渲染)</p>
</li>
<li><p>componentDidUpdate()：已经更新回调</p>
</li>
</ol>
<h3 id="移除组件：ReactDOM-unmountComponentAtNode-containerDom"><a href="#移除组件：ReactDOM-unmountComponentAtNode-containerDom" class="headerlink" title="移除组件：ReactDOM.unmountComponentAtNode(containerDom)"></a>移除组件：ReactDOM.unmountComponentAtNode(containerDom)</h3><ul>
<li>componentWillUnmount()：组件将要被移除回调</li>
</ul>
<h2 id="重要的勾子"><a href="#重要的勾子" class="headerlink" title="重要的勾子"></a>重要的勾子</h2><ol>
<li><p>render()：初始化渲染或更新渲染调用</p>
</li>
<li><p>componentDidMount()：开启监听，发送 ajax 请求</p>
</li>
<li><p>componentWillUnmount()：做一些收尾工作，如：清理定时器</p>
</li>
<li><p>componentWillReceiveProps()：</p>
</li>
</ol>
<h1 id="错误边界"><a href="#错误边界" class="headerlink" title="错误边界"></a>错误边界</h1><p>如果一个 class 组件中定义了 <code>static getDerivedStateFromError()</code> 或 <code>componentDidCatch()</code> 这两个生命周期方法中的任意一个（或两个）时，那么它就变成一个错误边界。当抛出错误后，请使用 <code>static getDerivedStateFromError()</code> 渲染备用 UI ，使用 <code>componentDidCatch()</code> 打印错误信息。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">class ErrorBoundary extends React.Component &#123;</span><br><span class="line">    constructor(props) &#123;</span><br><span class="line">        super(props);</span><br><span class="line">        this.state = &#123; hasError: false &#125;;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    static getDerivedStateFromError(error) &#123;</span><br><span class="line">        // 更新 state 使下一次渲染能够显示降级后的 UI</span><br><span class="line">        return &#123; hasError: true &#125;;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    componentDidCatch(error, info) &#123;</span><br><span class="line">        // 你同样可以将错误日志上报给服务器</span><br><span class="line">        logErrorToMyService(error, info);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    render() &#123;</span><br><span class="line">        if (this.state.hasError) &#123;</span><br><span class="line">        // 你可以自定义降级后的 UI 并渲染</span><br><span class="line">        return &lt;h1&gt;Something went wrong.&lt;/h1&gt;;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        return this.props.children; </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>然后你可以将它作为一个常规组件去使用：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;ErrorBoundary&gt;</span><br><span class="line">    &lt;MyWidget /&gt;</span><br><span class="line">&lt;/ErrorBoundary&gt;</span><br></pre></td></tr></table></figure>

<p>注意<strong>错误边界仅可以捕获其子组件的错误</strong>，它无法捕获其自身的错误。如果一个错误边界无法渲染错误信息，则错误会冒泡至最近的上层错误边界，这也类似于 JavaScript 中 catch {} 的工作机制。</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/10/29/React生命周期/" data-id="ck4r400rp0084l0w0k8ek8cpu" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/React/">React</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-React组件三大属性及组件通信" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/10/28/React组件三大属性及组件通信/" class="article-date">
  <time datetime="2019-10-28T07:28:29.000Z" itemprop="datePublished">2019-10-28</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/React/">React</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/10/28/React组件三大属性及组件通信/">React组件三大属性及组件通信</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="state"><a href="#state" class="headerlink" title="state"></a>state</h2><h3 id="初始化状态"><a href="#初始化状态" class="headerlink" title="初始化状态"></a>初始化状态</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">constructor(props)&#123;</span><br><span class="line">    super(props);</span><br><span class="line">    this.state=&#123;</span><br><span class="line">        stateProp: value1,</span><br><span class="line">        stateProp2: value2</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="读取某个状态值"><a href="#读取某个状态值" class="headerlink" title="读取某个状态值"></a>读取某个状态值</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">this.state.statePropertyName;</span><br></pre></td></tr></table></figure>

<h3 id="更新状态-–-gt-组件界面更新"><a href="#更新状态-–-gt-组件界面更新" class="headerlink" title="更新状态 –&gt; 组件界面更新"></a>更新状态 –&gt; 组件界面更新</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">this.setState(&#123;</span><br><span class="line">    stateProp1: value1,</span><br><span class="line">    stateProp2: value2</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>注意：在 JSX 的新添加的方法中，内部的 this 默认不是组件对象，而是 undefined。应该使用 bind 方法解决该问题</p>
<h2 id="props"><a href="#props" class="headerlink" title="props"></a>props</h2><h3 id="内部读取某个属性值"><a href="#内部读取某个属性值" class="headerlink" title="内部读取某个属性值"></a>内部读取某个属性值</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">this.props.propertyName</span><br></pre></td></tr></table></figure>

<h3 id="对-props-中的属性值进行类型限制和必要性限制"><a href="#对-props-中的属性值进行类型限制和必要性限制" class="headerlink" title="对 props 中的属性值进行类型限制和必要性限制"></a>对 props 中的属性值进行类型限制和必要性限制</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Person.propTypes = &#123;</span><br><span class="line">    name: React.PropTypes.string.isRequired,</span><br><span class="line">    age: React.PropTypes.number.isRequired</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="扩展属性：将对象的所有属性通过-props-传递"><a href="#扩展属性：将对象的所有属性通过-props-传递" class="headerlink" title="扩展属性：将对象的所有属性通过 props 传递"></a>扩展属性：将对象的所有属性通过 props 传递</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;Person&#123;...person&#125;&gt;</span><br></pre></td></tr></table></figure>

<h3 id="默认属性值"><a href="#默认属性值" class="headerlink" title="默认属性值"></a>默认属性值</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Person.defaultProps = &#123;</span><br><span class="line">    name: &apos;Mary&apos;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="ref"><a href="#ref" class="headerlink" title="ref"></a>ref</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;input type=&quot;text&quot; ref=&#123;(input) =&gt; &#123;this.input = input&#125;&#125;/&gt;</span><br></pre></td></tr></table></figure>

<h1 id="组件交互"><a href="#组件交互" class="headerlink" title="组件交互"></a>组件交互</h1><h2 id="父子组件"><a href="#父子组件" class="headerlink" title="父子组件"></a>父子组件</h2><h3 id="父组件传递给子组件"><a href="#父组件传递给子组件" class="headerlink" title="父组件传递给子组件"></a>父组件传递给子组件</h3><p>将要改变的数据传给子组件，子组件调用函数改变state</p>
<h3 id="子组件传递给父组件"><a href="#子组件传递给父组件" class="headerlink" title="子组件传递给父组件"></a>子组件传递给父组件</h3><p>子组件不能直接改变父组件的数据！！！</p>
<p>解决方案：父组件将要改变数据的函数传给子组件，子组件调用这个函数，进而改变父组件的数据</p>
<h1 id="组件通信"><a href="#组件通信" class="headerlink" title="组件通信"></a>组件通信</h1><h2 id="方式一：通过-props-传递"><a href="#方式一：通过-props-传递" class="headerlink" title="方式一：通过 props 传递"></a>方式一：通过 props 传递</h2><ol>
<li><p>共同的数据放在父组件上，特有的数据放在自己组件内部(state)</p>
</li>
<li><p>通过 props 可以传递一般数据和函数数据</p>
</li>
<li><p>一般数据 -&gt; 父组件传递数据给子组件 -&gt; 子组件读取数据</p>
</li>
<li><p>函数数据 -&gt; 子组件传递数据给父组件 -&gt; 子组件调用函数</p>
</li>
</ol>
<h2 id="方式二：使用消息订阅-subscribe-发布-publish-机制"><a href="#方式二：使用消息订阅-subscribe-发布-publish-机制" class="headerlink" title="方式二：使用消息订阅(subscribe)-发布(publish)机制"></a>方式二：使用消息订阅(subscribe)-发布(publish)机制</h2><ol>
<li><p>工具库：PubSubJS</p>
</li>
<li><p>下载：<code>npm install pubsub-js --save</code></p>
</li>
</ol>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/10/28/React组件三大属性及组件通信/" data-id="ck4r400rt008cl0w0tx75gdc9" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/React/">React</a></li></ul>

    </footer>
  </div>
  
</article>


  


  <nav id="page-nav">
    
    <a class="extend prev" rel="prev" href="/">&laquo; Prev</a><a class="page-number" href="/">1</a><span class="page-number current">2</span><a class="page-number" href="/page/3/">3</a><a class="page-number" href="/page/4/">4</a><span class="space">&hellip;</span><a class="page-number" href="/page/12/">12</a><a class="extend next" rel="next" href="/page/3/">Next &raquo;</a>
  </nav>

</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Categories</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/Ajax/">Ajax</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/CSS/">CSS</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/CSS3/">CSS3</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Dart/">Dart</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Flutter/">Flutter</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Git/">Git</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/HTML/">HTML</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/HTML5/">HTML5</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/JSON/">JSON</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Java/">Java</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/JavaScript/">JavaScript</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/QT/">QT</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/React/">React</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Sass/">Sass</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/TheKnowledgeOf/">TheKnowledgeOf</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/TypeScript/">TypeScript</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/bootstrap/">bootstrap</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/jQuery/">jQuery</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/tags/Ajax/">Ajax</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/CSS/">CSS</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/CSS3/">CSS3</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Dart/">Dart</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Flutter/">Flutter</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Git/">Git</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/HTML/">HTML</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/HTML5/">HTML5</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/JSON/">JSON</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Java/">Java</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/JavaScript/">JavaScript</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Javascript/">Javascript</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/QT/">QT</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/React/">React</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Sass/">Sass</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/TheKnowledgeOf/">TheKnowledgeOf</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/TypeScript/">TypeScript</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/bootstrap/">bootstrap</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/jQuery/">jQuery</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/tags/Ajax/" style="font-size: 12.22px;">Ajax</a> <a href="/tags/CSS/" style="font-size: 18.89px;">CSS</a> <a href="/tags/CSS3/" style="font-size: 17.78px;">CSS3</a> <a href="/tags/Dart/" style="font-size: 14.44px;">Dart</a> <a href="/tags/Flutter/" style="font-size: 16.67px;">Flutter</a> <a href="/tags/Git/" style="font-size: 12.22px;">Git</a> <a href="/tags/HTML/" style="font-size: 14.44px;">HTML</a> <a href="/tags/HTML5/" style="font-size: 12.22px;">HTML5</a> <a href="/tags/JSON/" style="font-size: 10px;">JSON</a> <a href="/tags/Java/" style="font-size: 11.11px;">Java</a> <a href="/tags/JavaScript/" style="font-size: 20px;">JavaScript</a> <a href="/tags/Javascript/" style="font-size: 10px;">Javascript</a> <a href="/tags/QT/" style="font-size: 12.22px;">QT</a> <a href="/tags/React/" style="font-size: 15.56px;">React</a> <a href="/tags/Sass/" style="font-size: 11.11px;">Sass</a> <a href="/tags/TheKnowledgeOf/" style="font-size: 11.11px;">TheKnowledgeOf</a> <a href="/tags/TypeScript/" style="font-size: 10px;">TypeScript</a> <a href="/tags/bootstrap/" style="font-size: 11.11px;">bootstrap</a> <a href="/tags/jQuery/" style="font-size: 13.33px;">jQuery</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/12/">December 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/11/">November 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/10/">October 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/09/">September 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/08/">August 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/07/">July 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/06/">June 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/05/">May 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/04/">April 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/03/">March 2019</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2019/12/29/Flutter-MaterialApp常用属性介绍/">Flutter-MaterialApp常用属性介绍</a>
          </li>
        
          <li>
            <a href="/2019/12/29/Flutter-ListView/">Flutter-ListView</a>
          </li>
        
          <li>
            <a href="/2019/12/29/Flutter-AppBar/">Flutter-AppBar</a>
          </li>
        
          <li>
            <a href="/2019/12/29/Flutter-TabBar/">Flutter-TabBar</a>
          </li>
        
          <li>
            <a href="/2019/12/29/Flutter-按钮/">Flutter-按钮</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2019 John Doe<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/script.js"></script>



  </div>
</body>
</html>